#include "StdAfx.h"
#include "ObservationTowerFactory.h"
#include "sgcomposite.h"
#include "sgrotate.h"
#include "sgsphere.h"
#include "sgptr.h"
#include "sgseparator.h"
#include "sgcylinder.h"
#include "sgoctagonalcylinder.h"
#include "sgmaterial.h"
#include "sgtexture.h"
#include <cmath>

const double GR_PI = 3.1415926535897932384626433832795;

ObservationTowerFactory::ObservationTowerFactory(void)
{
	m_ObservationTower = new CSgComposite();
	m_texture1 = new CTexture();
	m_texture1->LoadFile(L"CedarPoint_Logo.bmp");
	m_texture2 = new CTexture();
	m_texture2->LoadFile(L"ride.bmp");
	m_texture3 = new CTexture();
	m_texture3->LoadFile(L"canada.bmp");
	m_texture4 = new CTexture();
	m_texture4->LoadFile(L"marble02.bmp");

	m_car_degrees = 0;
	m_car_height = 0.0;
	m_offset = 0.0;
}

ObservationTowerFactory::~ObservationTowerFactory(void)
{
	delete m_texture1;
	delete m_texture2;
	delete m_texture3;
	delete m_texture4;
}
void ObservationTowerFactory::AdvanceTime(const DWORD & timeDiff, const DWORD & currentTime)
{
	float test = (float)(timeDiff/1000);
	float temp = fmod(test, 132);
	const int incrementDegrees = (int)((double)timeDiff / 85.);
	const double incrementHeight = ((double)timeDiff / 293.066666666666666666667);
	float temp2 = (float(fmod(fmod((currentTime/1000.0), 51.0), 21)));
	float temp3 = (float(fmod(fmod((currentTime/1000.0), 51.0), 9.0)));
	m_car_degrees = (incrementDegrees) % 360;
	m_car_height = fmod(incrementHeight, 75.078);
	if(temp < 22)
	{
		if (m_rotate_point_1 != NULL)
		{
			m_car_height += m_offset;
			m_rotate_point_1->SetDegrees(m_car_degrees);
			m_translate->SetTranslate(0., m_car_height, 0.);
			if(m_car_height > m_total_height)
				m_total_height = m_car_height;

			else
			{
				// Makes sure that the height isn't reset when the 
				if(temp <=1)
				{
					m_total_height = 0.0;
				}
			}

		}
	}
	else if(temp >=22 && temp <66)
	{
		m_translate->SetTranslate(0., m_total_height, 0.);
		m_rotate_point_1->SetDegrees(m_car_degrees);
	}
	else if(temp >= 66 && temp < 88)
	{
		int xx = 0;
		if (m_rotate_point_1 != NULL)
		{
			bool tester = false;
			//m_car_down_height = fmod(incrementHeight, 150);
			double down_position = m_total_height - m_car_height;
			m_rotate_point_1->SetDegrees(m_car_degrees);
			m_translate->SetTranslate(0., down_position, 0.);

			if(down_position <= 0.3)
				int xx = 0;
			if(m_car_height >= m_total_height - 1)
			{
				if(tester)
				{
					int xx = 0;
				}
				tester = true;
			}
		}
	}
	else
	{
		if(m_rotate_point_1 != NULL)
		{
			m_rotate_point_1->SetDegrees(0.0);
			m_translate->SetTranslate(0., 0., 0.);
		}
	}

}
CSgObject* ObservationTowerFactory::Create()
{
	CSgPtr<CSgComposite> temp = new CSgComposite();
	CSgPtr<CSgRotateAroundPoint> anim_rot = new CSgRotateAroundPoint(0, 0, 6, 2, 0, 1, 0);
	CSgPtr<CSgTranslate> anim_trans = new CSgTranslate(CGrVector(0., 1., 0.));
	m_rotate_point_1 = anim_rot;
	m_translate = anim_trans;
	CSgPtr<CSgComposite> base = new CSgComposite();
	base = CreateBase();
	CSgPtr<CSgComposite> pole = new CSgComposite();
	pole = CreatePole();
	CSgPtr<CSgComposite> car = new CSgComposite();
	car = CreateCar();
	CSgPtr<CSgComposite> antenna = new CSgComposite();
	antenna = CreateAntenna();
	CSgPtr<CSgSeparator> sep4 = new CSgSeparator();
	CSgPtr<CSgTranslate> trs4 = new CSgTranslate(CGrVector(0., 80., 0.));
	trs4->SetChild(antenna);
	sep4->SetChild(trs4);

	temp->AddChild(base);
	temp->AddChild(pole);
	temp->AddChild(sep4);

	CSgPtr<CSgComposite> sign = new CSgComposite();
	sign = CreateSign();
	temp->AddChild(sign);

	anim_rot->SetChild(car);
	anim_trans->SetChild(anim_rot);
	temp->AddChild(anim_trans);


	m_ObservationTower->AddChild(temp);


	return m_ObservationTower;

}

CSgPtr<CSgComposite> ObservationTowerFactory::CreateBase()
{
	CSgPtr<CSgComposite> m_base = new CSgComposite();

	double v[8][4] = {{0., 0., 0., 1.},{4., 0., 0., 1.}, {4., 0., 4., 1.},
						{0., 0., 4., 1.}, {0., 2., 0., 1.}, {4., 2., 0., 1.},
						{4., 2., 4., 1.}, {0., 2., 4., 1.}};
    double n[6][4] = {{0, 0, 1, 0}, {1, 0, 0, 0}, {0, 0, -1, 0}, 
						{-1, 0, 0, 0}, {0, 1, 0, 0}, {0, -1, 0, 0}};

	double t[4][2] = {{0, 0}, {0,1}, {1, 0}, {1,1}};

	CSgPtr<CSgTexture> tex1 = new CSgTexture(m_texture1);
	CSgPtr<CSgTexture> tex2 = new CSgTexture(m_texture1);
	CSgPtr<CSgTexture> tex3 = new CSgTexture(m_texture4);

	CSgPtr<CSgPolygon> bottom = new CSgPolygon();
	bottom->AddNormal(CGrVector(n[5]));
	bottom->AddTexCoord(CGrVector(t[1]));
	bottom->AddVertex(CGrVector(v[0]));
	bottom->AddTexCoord(CGrVector(t[0]));
	bottom->AddVertex(CGrVector(v[1]));
	bottom->AddTexCoord(CGrVector(t[2]));
	bottom->AddVertex(CGrVector(v[2]));
	bottom->AddTexCoord(CGrVector(t[3]));
	bottom->AddVertex(CGrVector(v[3]));

	m_base->AddChild(bottom);

	CSgPtr<CSgPolygon> left = new CSgPolygon();
	left->AddNormal(CGrVector(n[3]));
	left->AddTexCoord(CGrVector(t[1]));
	left->AddVertex(CGrVector(v[4]));
	left->AddTexCoord(CGrVector(t[0]));
	left->AddVertex(CGrVector(v[0]));
	left->AddTexCoord(CGrVector(t[2]));
	left->AddVertex(CGrVector(v[3]));
	left->AddTexCoord(CGrVector(t[3]));
	left->AddVertex(CGrVector(v[7]));

	tex1->SetChild(left);
	m_base->AddChild(tex1);
	

	CSgPtr<CSgPolygon> right = new CSgPolygon();

	right->AddNormal(CGrVector(n[1]));
	right->AddTexCoord(CGrVector(t[2]));
	right->AddVertex(CGrVector(v[1]));
	right->AddTexCoord(CGrVector(t[3]));
	right->AddVertex(CGrVector(v[5]));
	right->AddTexCoord(CGrVector(t[1]));
	right->AddVertex(CGrVector(v[6]));
	right->AddTexCoord(CGrVector(t[0]));
	right->AddVertex(CGrVector(v[2]));

	tex2->SetChild(right);
	m_base->AddChild(tex2);

	CSgPtr<CSgPolygon> back = new CSgPolygon();

	back->AddNormal(CGrVector(n[2]));
	back->AddTexCoord(CGrVector(t[0]));
	back->AddVertex(CGrVector(v[0]));
	back->AddTexCoord(CGrVector(t[2]));
	back->AddVertex(CGrVector(v[4]));
	back->AddTexCoord(CGrVector(t[3]));
	back->AddVertex(CGrVector(v[5]));
	back->AddTexCoord(CGrVector(t[1]));
	back->AddVertex(CGrVector(v[1]));

	m_base->AddChild(back);

	CSgPtr<CSgPolygon> front = new CSgPolygon();

	front->AddNormal(CGrVector(n[0]));
	front->AddTexCoord(CGrVector(t[0]));
	front->AddVertex(CGrVector(v[3]));
	front->AddTexCoord(CGrVector(t[2]));
	front->AddVertex(CGrVector(v[2]));
	front->AddTexCoord(CGrVector(t[3]));
	front->AddVertex(CGrVector(v[6]));
	front->AddTexCoord(CGrVector(t[1]));
	front->AddVertex(CGrVector(v[7]));

	tex3->SetChild(front);
	CSgPtr<CSgSeparator> sep10 = new CSgSeparator();
	sep10->SetChild(tex3);
	m_base->AddChild(sep10);

	CSgPtr<CSgPolygon> top = new CSgPolygon();

	top->AddNormal(CGrVector(n[4]));
	top->AddTexCoord(CGrVector(t[0]));
	top->AddVertex(CGrVector(v[5]));
	top->AddTexCoord(CGrVector(t[2]));
	top->AddVertex(CGrVector(v[4]));
	top->AddTexCoord(CGrVector(t[3]));
	top->AddVertex(CGrVector(v[7]));
	top->AddTexCoord(CGrVector(t[1]));
	top->AddVertex(CGrVector(v[6]));

	m_base->AddChild(top);

	CSgPtr<CSgComposite> final = new CSgComposite();
	CSgPtr<CSgTranslate> trs = new CSgTranslate(-2., -1., 0.);
	trs->SetChild(m_base);

	CSgPtr<CSgSeparator> sep = new CSgSeparator();
	sep->SetChild(trs);
	final->AddChild(sep);


	return final;
	//m_ObservationTower->AddChild(m_base);

}

CSgPtr<CSgComposite> ObservationTowerFactory::CreatePole()
{
	CSgPtr<CSgComposite> pole = new CSgComposite();
	
	double m_pole_radius = 1.0;
	CSgPtr<CSgCylinder> cyl = new CSgCylinder(85., m_pole_radius);
	CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
	CSgPtr<CSgTranslate> trs2 = new CSgTranslate(0., 1., 2.);

	trs2->SetChild(cyl);
	sep2->SetChild(trs2);
	pole->AddChild(sep2);
	//m_ObservationTower->AddChild(pole);

	CSgPtr<CSgComposite> m_rail = new CSgComposite();
	m_rail = CreateRail(m_pole_radius);
	pole->AddChild(m_rail);

	return pole;

	//m_ObservationTower->AddChild(m_rail);


}

CSgPtr<CSgComposite> ObservationTowerFactory::CreateCar()
{
	CSgPtr<CSgComposite> car = new CSgComposite();

	car->AddChild(InsideWall());
	car->AddChild(OutsideWall());	

	CSgPtr<CSgMaterial> mat1 = new CSgMaterial(50.f, 0.698039216f, 0.133333333f, 0.133333333f, 1.0f, 0.698039216f, 0.133333333f, 0.133333333f, 1.0f); 

	
	CSgPtr<CSgComposite> m_top = new CSgComposite();

	m_top = CreateDoughnut(1.7, 3.7);
	CSgPtr<CSgTranslate> trs = new CSgTranslate(0., 6., 0.);
	CSgPtr<CSgSeparator> sep1 = new CSgSeparator();
	trs->SetChild(m_top);
	mat1->SetChild(trs);
	sep1->SetChild(mat1);
	car->AddChild(sep1);

	CSgPtr<CSgComposite> m_bottom = new CSgComposite();
	
	m_bottom = CreateDoughnut(1.7, 3.7);
	CSgPtr<CSgRotateAroundPoint> rot = new CSgRotateAroundPoint(180, CGrVector(0., 4., 2.), CGrVector(1., 0., 0.));
	CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
	
	rot->SetChild(m_bottom);
	sep2->SetChild(rot);
	car->AddChild(sep2);

	CSgPtr<CSgComposite> m_top_bottom_half = new CSgComposite(); 
	m_top_bottom_half = CreateDoughnut(1.7, 3.7);
	CSgPtr<CSgRotateAroundPoint> rot2 = new CSgRotateAroundPoint(180, CGrVector(0., 4., 2.), CGrVector(1., 0., 0.));
	CSgPtr<CSgSeparator> sep3 = new CSgSeparator();
	CSgPtr<CSgTranslate> trs2 = new CSgTranslate(0., 5.7, 0.);

	rot2->SetChild(m_top_bottom_half);
	trs2->SetChild(rot2);
	sep3->SetChild(trs2);
	car->AddChild(sep3);

	CSgPtr<CSgComposite> m_bottom_top_half = new CSgComposite(); 
	m_bottom_top_half = CreateDoughnut(1.7, 3.7);
	CSgPtr<CSgTranslate> trs3 = new CSgTranslate(0., .3,0.);
	CSgPtr<CSgSeparator> sep4 = new CSgSeparator();
	
	trs3->SetChild(m_bottom_top_half);
	sep4->SetChild(trs3);
	car->AddChild(sep4);

	CSgPtr<CSgComposite> m_top_wall_1 = new CSgComposite();
	m_top_wall_1 = Shell(.3, 3.7);
	CSgPtr<CSgTranslate> trs4 = new CSgTranslate(0., 5.7, 0.);
	CSgPtr<CSgSeparator> sep5 = new CSgSeparator();
	trs4->SetChild(m_top_wall_1);
	sep5->SetChild(trs4);
	car->AddChild(sep5);
	
	CSgPtr<CSgComposite> m_bottom_wall_1 = new CSgComposite();
	m_bottom_wall_1 = Shell(.3, 3.7);
	CSgPtr<CSgSeparator> sep6 = new CSgSeparator();
	sep6->SetChild(m_bottom_wall_1);
	car->AddChild(sep6);

	CSgPtr<CSgMaterial> mat9 = new CSgMaterial(50.0f, 1.0f, 0.647058824f, 0.f, 1.0f, 1.0f, 0.647058824f, 0.f, 1.0f);
	CSgPtr<CSgComposite> m_floor_outside = new CSgComposite();
	m_floor_outside = m_bottom_wall_1;
	CSgPtr<CSgTranslate> trs5 = new CSgTranslate(CGrVector(0., 2.85, 0.));
	trs5->SetChild(m_floor_outside);
	CSgPtr<CSgSeparator> sep7 = new CSgSeparator();
	mat9->SetChild(trs5);
	sep7->SetChild(mat9);
	car->AddChild(sep7);

	CSgPtr<CSgComposite> m_floor_top = new CSgComposite();
	m_floor_top = m_bottom_top_half;
	CSgPtr<CSgTranslate> trs6 = new CSgTranslate(CGrVector(0., 3.15, 0.));
	CSgPtr<CSgSeparator> sep8 = new CSgSeparator();
	trs6->SetChild(m_floor_top);
	sep8->SetChild(trs6);
	car->AddChild(sep8);

	CSgPtr<CSgComposite> m_floor_bottom = new CSgComposite();
	m_floor_bottom = m_bottom;
	CSgPtr<CSgRotateAroundPoint> rot5 = new CSgRotateAroundPoint(180, CGrVector(0.,4.,2.), CGrVector(1., 0., 0.));
	CSgPtr<CSgTranslate> trs7 = new CSgTranslate(CGrVector(0., 2.85, 0.));
	CSgPtr<CSgSeparator> sep9 = new CSgSeparator();
	rot5->SetChild(m_floor_bottom);
	trs7->SetChild(rot5);
	sep9->SetChild(trs7);
	car->AddChild(sep9);

	CSgPtr<CSgMaterial> mat10 = new CSgMaterial(50.0f,0.f, 0.392156863f, 0.f, 1.0f, 0.f, 0.392156863f, 0., 1.0f);
	CSgPtr<CSgComposite> m_bottom_bench = new CSgComposite();
	m_bottom_bench = CreateBench();
	CSgPtr<CSgSeparator> sep10 = new CSgSeparator();
	mat10->SetChild(m_bottom_bench);
	sep10->SetChild(mat10);

	car->AddChild(sep10);

	CSgPtr<CSgComposite> m_top_bench = new CSgComposite();
	m_top_bench = CreateBench();
	CSgPtr<CSgTranslate> trs8 = new CSgTranslate(CGrVector(0., 2.85, 0.));
	CSgPtr<CSgSeparator> sep11 = new CSgSeparator();
	trs8->SetChild(m_top_bench);
	sep11->SetChild(trs8);
	car->AddChild(sep11);

	CSgPtr<CSgMaterial> mat3 = new CSgMaterial(50.f, 0.f, 0.f, .7843137f, 1.f, 0.f, 0.f, .7843137f, 1.f);
	CSgPtr<CSgComposite> m_lower_posts = new CSgComposite();
	unsigned m_post_num = 10;
	for(unsigned i = 0; i< m_post_num;i++)
	{
		double angle = GR_PI*2/m_post_num;
		CSgPtr<CSgOctagonalCylinder> post = new CSgOctagonalCylinder(2.575f, 0.04f);
		CSgPtr<CSgSeparator> sep5 = new CSgSeparator();
		CSgPtr<CSgTranslate> trs5 = new CSgTranslate(CGrVector(3.65 * cos(angle * i),5.575, 3.65 * sin(angle * i) + 2));
		trs5->SetChild(post);
		sep5->SetChild(trs5);

		m_lower_posts->AddChild(sep5);

	}
	CSgPtr<CSgSeparator> sep12 = new CSgSeparator();
	
	mat3->SetChild(m_lower_posts);
	sep6->SetChild(mat3);
	car->AddChild(sep12);

	CSgPtr<CSgComposite> m_upper_posts = new CSgComposite();
	CSgPtr<CSgMaterial> mat4 = new CSgMaterial(50.f, 0.f, 0.f, .7843137f, 1.f, 0.f, 0.f, .7843137f, 1.f);

	for(unsigned i = 0; i< m_post_num;i++)
	{
		double angle = GR_PI*2/m_post_num;
		CSgPtr<CSgOctagonalCylinder> post = new CSgOctagonalCylinder(2.55f, 0.04f);
		CSgPtr<CSgSeparator> sep5 = new CSgSeparator();
		CSgPtr<CSgTranslate> trs5 = new CSgTranslate(CGrVector(3.65 * cos(angle * i),8.45, 3.65 * sin(angle * i) + 2));
		trs5->SetChild(post);
		sep5->SetChild(trs5);

		m_upper_posts->AddChild(sep5);

	}
	CSgPtr<CSgSeparator> sep13 = new CSgSeparator();
	mat4->SetChild(m_lower_posts);
	sep13->SetChild(mat4);
	car->AddChild(sep13);
	car->AddChild(m_upper_posts);

	

	return car;


}
CSgPtr<CSgComposite> ObservationTowerFactory::InsideWall(void)
{
	CSgPtr<CSgComposite> m_outsideWall = new CSgComposite();
	CSgPtr<CSgComposite> temp = new CSgComposite();
	CSgPtr<CSgMaterial> mat3 = new CSgMaterial(50.f, 0.698039216f, 0.133333333f, 0.133333333f, 1.0f, 0.698039216f, 0.133333333f, 0.133333333f, 1.0f); 
	CSgPtr<CSgSeparator> sep = new CSgSeparator();
	temp = InverseShell(6., 1.7);
	mat3->SetChild(temp);
	sep->SetChild(mat3);
	m_outsideWall->AddChild(sep);
	return m_outsideWall;
}

CSgPtr<CSgComposite> ObservationTowerFactory::OutsideWall(void)
{

	CSgPtr<CSgComposite> m_insideWall = new CSgComposite();

	m_insideWall = Shell(6., 2.0);
	return m_insideWall;
}


CSgPtr<CSgComposite> ObservationTowerFactory::CreateDoughnut(double m_in_radius, double m_out_radius)
{
	CSgPtr<CSgComposite> m_top = new CSgComposite();

	CSgPtr<CSgMesh> m_doughnut = new CSgMesh();

	unsigned m_side_num = 20;

	double top_center[] = {0., 0., 0.};
	m_doughnut->AddNormal(CGrVector(0., 1.,0.));
	for(unsigned j = 0; j<m_side_num;j++)
	{
		double angle = (2*GR_PI)/m_side_num;
		double out_vertex[] = {top_center[0] + m_out_radius * sin(angle * j), top_center[1], top_center[2] + m_out_radius * cos(angle * j), 0};
		double in_vertex[] = {top_center[0] + m_in_radius * sin(angle * j), top_center[1], top_center[2] + m_in_radius * cos(angle * j), 0};

		m_doughnut->AddVertex( out_vertex );
		m_doughnut->AddVertex( in_vertex );			

		if( j == 0)
			continue;
		
		unsigned tl = j*2-2;
		unsigned ll = j*2-1;
		unsigned lr = j*2+1;
		unsigned tr = j*2;
		//First triangle of square
		m_doughnut->AddTriangleVertex(tl, 0, -1);
		m_doughnut->AddTriangleVertex(lr, 0, -1);
		m_doughnut->AddTriangleVertex(ll, 0, -1);

		//Second triangle of square
		m_doughnut->AddTriangleVertex(tr, 0, -1);
		m_doughnut->AddTriangleVertex(lr, 0, -1);
		m_doughnut->AddTriangleVertex(tl, 0 ,-1);	
	}

	m_doughnut->AddTriangleVertex(1, 0, -1);
	m_doughnut->AddTriangleVertex((m_side_num*2) -1, 0, -1);
	m_doughnut->AddTriangleVertex((m_side_num*2) - 2, 0, -1);

	m_doughnut->AddTriangleVertex(0, 0, -1);
	m_doughnut->AddTriangleVertex(1, 0, -1);
	m_doughnut->AddTriangleVertex((m_side_num*2) -2, 0 ,-1);

	CSgPtr<CSgTranslate> trans = new CSgTranslate(0., 4., 2.);
	CSgPtr<CSgSeparator> sep = new CSgSeparator();
	trans->SetChild(m_doughnut);
	sep->SetChild(trans);
	m_top->AddChild(sep);

	return m_top;
	//m_ObservationTower->AddChild(m_top);
}

CSgPtr<CSgComposite> ObservationTowerFactory::Shell(double m_height, double m_radius)
{
	CSgPtr<CSgComposite> m_insideWall = new CSgComposite();

	CSgPtr<CSgMesh> m_inside = new CSgMesh();
	unsigned m_side_num = 20;
	unsigned m_height_num = 5;
	double height_step = m_height/m_height_num;
	unsigned count1 = 0;

	for(double k = 0.0; k<m_height; k+= height_step)
	{	
		double center[] = {0.0, k, 0.0};
		double top_center[] = {0.0, k+height_step , 0.0};
		
		for(unsigned j = 0; j<m_side_num;j++)
		{
			double angle = (2*GR_PI)/m_side_num;
			double top_vertex[] = {top_center[0] + m_radius * sin(angle * j), top_center[1], top_center[2] + m_radius * cos(angle * j), 0};
			double bottom_vertex[] = {center[0] + m_radius * sin(angle * j), center[1], center[2] + m_radius * cos(angle * j), 0};
	
			m_inside->AddVertex( top_vertex );
			m_inside->AddVertex( bottom_vertex );


			if(k == 0.0)
				m_inside->AddNormal(CGrVector(sin(angle *j), 0, cos(angle*j)));

			if( j == 0)
				continue;
			
			unsigned temp= count1*(m_side_num*2);
			unsigned tl = j*2-2;
			unsigned ll = j*2-1;
			unsigned lr = j*2+1;
			unsigned tr = j*2;
			int test = temp + tl;
			//First triangle of square
			m_inside->AddTriangleVertex(temp+tl, j, -1);
			m_inside->AddTriangleVertex(temp+ll, j, -1);
			m_inside->AddTriangleVertex(temp+lr, j, -1);

			//Second triangle of square
			m_inside->AddTriangleVertex(temp+tl, j, -1);
			m_inside->AddTriangleVertex(temp+lr, j, -1);
			m_inside->AddTriangleVertex(temp+tr, j ,-1);	
		}	
		unsigned temp2 = (count1*m_side_num*2);
		m_inside->AddTriangleVertex(temp2+(m_side_num*2) - 2, 0, -1);
		m_inside->AddTriangleVertex(temp2+(m_side_num*2) -1, 0, -1);
		m_inside->AddTriangleVertex(temp2+1, 0, -1);

		m_inside->AddTriangleVertex(temp2+(m_side_num*2) -2, 0, -1);
		m_inside->AddTriangleVertex(temp2+1, 0, -1);
		m_inside->AddTriangleVertex(temp2+0, 0 ,-1);
		count1++;
	}
	CSgPtr<CSgTranslate> trans = new CSgTranslate(0., 4., 2.);
	CSgPtr<CSgSeparator> sep = new CSgSeparator();
	trans->SetChild(m_inside);
	sep->SetChild(trans);
	m_insideWall->AddChild(sep);
	return m_insideWall;
}

CSgPtr<CSgComposite> ObservationTowerFactory::InverseShell(double m_height, double m_radius)
{
	CSgPtr<CSgComposite> m_outsideWall = new CSgComposite();
	CSgPtr<CSgMesh> m_outside = new CSgMesh();
	unsigned m_side_num = 20;
	unsigned m_height_num = 5;
	double height_step = m_height/m_height_num;
	unsigned count1 = 0;


	for(double k = 0.0; k<m_height; k+= height_step)
	{	
		double center[] = {0.0, k, 0.0};
		double top_center[] = {0.0, k+height_step , 0.0};
		
		for(unsigned j = 0; j<m_side_num;j++)
		{
			double angle = (2*GR_PI)/m_side_num;
			double top_vertex[] = {top_center[0] + m_radius * sin(angle * j), top_center[1], top_center[2] + m_radius * cos(angle * j), 0};
			double bottom_vertex[] = {center[0] + m_radius * sin(angle * j), center[1], center[2] + m_radius * cos(angle * j), 0};
	
			m_outside->AddVertex( top_vertex );
			m_outside->AddVertex( bottom_vertex );


			if(k == 0.0)
				m_outside->AddNormal(CGrVector(sin(angle *j), 0, cos(angle*j)));

			if( j == 0)
				continue;
			
			unsigned temp= count1*(m_side_num*2);
			unsigned tl = j*2-2;
			unsigned ll = j*2-1;
			unsigned lr = j*2+1;
			unsigned tr = j*2;
			//First triangle of square
			m_outside->AddTriangleVertex(temp+lr, j, -1);
			m_outside->AddTriangleVertex(temp+ll, j, -1);
			m_outside->AddTriangleVertex(temp+tl, j, -1);

			//Second triangle of square
			m_outside->AddTriangleVertex(temp+tr, j, -1);
			m_outside->AddTriangleVertex(temp+lr, j, -1);
			m_outside->AddTriangleVertex(temp+tl, j ,-1);	
		}	
		unsigned temp2 = (count1*m_side_num*2);
		m_outside->AddTriangleVertex(temp2+1, 0, -1);
		m_outside->AddTriangleVertex(temp2+(m_side_num*2) -1, 0, -1);
		m_outside->AddTriangleVertex(temp2+(m_side_num*2) - 2, 0, -1);

		m_outside->AddTriangleVertex(temp2+0, 0, -1);
		m_outside->AddTriangleVertex(temp2+1, 0, -1);
		m_outside->AddTriangleVertex(temp2+(m_side_num*2) -2, 0 ,-1);
		count1++;
	}
	CSgPtr<CSgTranslate> trans = new CSgTranslate(0., 4., 2.);
	CSgPtr<CSgSeparator> sep = new CSgSeparator();
	trans->SetChild(m_outside);
	sep->SetChild(trans);
	m_outsideWall->AddChild(sep);

	return m_outsideWall;
}

CSgPtr<CSgComposite> ObservationTowerFactory::CreateRail(double m_radius)
{
	CSgPtr<CSgComposite> m_rail = new CSgComposite();
	
	CSgPtr<CSgComposite> m_handrail_top = new CSgComposite();
	m_handrail_top = CreateDoughnut(0.9, 1.0);
	CSgPtr<CSgTranslate> trs1 = new CSgTranslate(0., 82.5, 0.);
	CSgPtr<CSgSeparator> sep1 = new CSgSeparator();
	trs1->SetChild(m_handrail_top);
	sep1->SetChild(trs1);
	m_rail->AddChild(sep1);
	

	CSgPtr<CSgComposite> m_handrail_bottom = new CSgComposite();
	m_handrail_bottom = CreateDoughnut(0.9, 1.0);
	CSgPtr<CSgRotateAroundPoint> rotap1 = new CSgRotateAroundPoint(180, CGrVector(0., 4., 2.), CGrVector(1.,0., 0.));
	CSgPtr<CSgTranslate> trs2 = new CSgTranslate(0., 82.4, 0.);//82.4
	CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
	rotap1->SetChild(m_handrail_bottom);
	trs2->SetChild(rotap1);
	sep2->SetChild(trs2);
	m_rail->AddChild(sep2);

	CSgPtr<CSgComposite> m_handrail_outside = new CSgComposite();
	m_handrail_outside = Shell(.1, 1.0);
	CSgPtr<CSgTranslate> trs3 = new CSgTranslate(0., 82.4, 0.); //82.4
	CSgPtr<CSgSeparator> sep4 = new CSgSeparator();
	
	trs3->SetChild(m_handrail_outside);
	sep4->SetChild(trs3);
	m_rail->AddChild(sep4);

	CSgPtr<CSgComposite> m_handrail_inside = new CSgComposite();
	m_handrail_inside = InverseShell(.1, 0.9);
	CSgPtr<CSgTranslate> trs4 = new CSgTranslate(CGrVector(0., 82.4, 0.));
	CSgPtr<CSgSeparator> sep6 = new CSgSeparator();

	trs4->SetChild(m_handrail_inside);
	sep6->SetChild(trs4);
	m_rail->AddChild(sep6);

	// coming back to
	CSgPtr<CSgComposite> m_posts = new CSgComposite();
	unsigned m_post_num = 10;
	for(unsigned i = 0; i< m_post_num;i++)
	{
		double angle = GR_PI*2/m_post_num;
		CSgPtr<CSgOctagonalCylinder> post = new CSgOctagonalCylinder(.4f, 0.04f);
		CSgPtr<CSgSeparator> sep5 = new CSgSeparator();
		CSgPtr<CSgTranslate> trs5 = new CSgTranslate(CGrVector(m_radius * cos(angle * i)*0.95, 2.35, m_radius * sin(angle * i)*0.95));
		trs5->SetChild(post);
		sep5->SetChild(trs5);

		m_posts->AddChild(sep5);

	}
	CSgPtr<CSgTranslate> trs6 = new CSgTranslate(CGrVector(0., 83.85,2.));
	trs6->SetChild(m_posts);
	m_rail->AddChild(trs6);
	return m_rail;
}
CSgPtr<CSgComposite> ObservationTowerFactory::CreateAntenna(void)
{
	CSgPtr<CSgComposite> m_antenna = new CSgComposite();

	CSgPtr<CSgComposite> m_bottom = new CSgComposite();
	m_bottom = ConicalFrustum(2, .1, 0.05);
	CSgPtr<CSgSeparator> sep = new CSgSeparator();
	CSgPtr<CSgTranslate> trs1 = new CSgTranslate(0,6, 2);//85
	trs1->SetChild(m_bottom);
	sep->SetChild(trs1);
	m_antenna->AddChild(sep);

	CSgPtr<CSgComposite> m_middle = new CSgComposite();
	m_middle = ConicalFrustum(2, .04, 0.02);
	CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
	CSgPtr<CSgTranslate> trs2 = new CSgTranslate(0,8, 2);//87
	trs2->SetChild(m_middle);
	sep2->SetChild(trs2);
	m_antenna->AddChild(sep2);
	
	CSgPtr<CSgComposite> flag = new CSgComposite();
	double v[8][4] = {{0., 0., 0., 1.},{2, 0., 0., 1.}, {2, 0., 0.1, 1.},
						{0., 0., 0.1, 1.}, {0., 2., 0., 1.}, {2, 2., 0., 1.},
						{2, 2., 0.1, 1.}, {0., 2., 0.1, 1.}};
    double n[6][4] = {{0, 0, 1, 0}, {1, 0, 0, 0}, {0, 0, -1, 0}, 
						{-1, 0, 0, 0}, {0, 1, 0, 0}, {0, -1, 0, 0}};

	double t[4][2] = {{0, 0}, {0,1}, {1, 0}, {1,1}};

	CSgPtr<CSgTexture> tex1 = new CSgTexture(m_texture3);
	CSgPtr<CSgTexture> tex2 = new CSgTexture(m_texture3);

	CSgPtr<CSgPolygon> bottom = new CSgPolygon();
	bottom->AddNormal(CGrVector(n[5]));
	bottom->AddTexCoord(CGrVector(t[1]));
	bottom->AddVertex(CGrVector(v[0]));
	bottom->AddTexCoord(CGrVector(t[0]));
	bottom->AddVertex(CGrVector(v[1]));
	bottom->AddTexCoord(CGrVector(t[2]));
	bottom->AddVertex(CGrVector(v[2]));
	bottom->AddTexCoord(CGrVector(t[3]));
	bottom->AddVertex(CGrVector(v[3]));

	flag->AddChild(bottom);

	CSgPtr<CSgPolygon> left = new CSgPolygon();
	left->AddNormal(CGrVector(n[3]));
	left->AddTexCoord(CGrVector(t[1]));
	left->AddVertex(CGrVector(v[4]));
	left->AddTexCoord(CGrVector(t[0]));
	left->AddVertex(CGrVector(v[0]));
	left->AddTexCoord(CGrVector(t[2]));
	left->AddVertex(CGrVector(v[3]));
	left->AddTexCoord(CGrVector(t[3]));
	left->AddVertex(CGrVector(v[7]));

	flag->AddChild(left);
	

	CSgPtr<CSgPolygon> right = new CSgPolygon();

	right->AddNormal(CGrVector(n[1]));
	right->AddTexCoord(CGrVector(t[2]));
	right->AddVertex(CGrVector(v[1]));
	right->AddTexCoord(CGrVector(t[3]));
	right->AddVertex(CGrVector(v[5]));
	right->AddTexCoord(CGrVector(t[1]));
	right->AddVertex(CGrVector(v[6]));
	right->AddTexCoord(CGrVector(t[0]));
	right->AddVertex(CGrVector(v[2]));

	flag->AddChild(right);

	CSgPtr<CSgPolygon> back = new CSgPolygon();

	back->AddNormal(CGrVector(n[2]));
	back->AddTexCoord(CGrVector(t[2]));
	back->AddVertex(CGrVector(v[0]));
	back->AddTexCoord(CGrVector(t[3]));
	back->AddVertex(CGrVector(v[4]));
	back->AddTexCoord(CGrVector(t[1]));
	back->AddVertex(CGrVector(v[5]));
	back->AddTexCoord(CGrVector(t[0]));
	back->AddVertex(CGrVector(v[1]));

	tex2->SetChild(back);
	CSgPtr<CSgSeparator> sep5 = new CSgSeparator();
	sep5->SetChild(tex2);
	flag->AddChild(sep5);

	CSgPtr<CSgPolygon> front = new CSgPolygon();

	front->AddNormal(CGrVector(n[0]));
	front->AddTexCoord(CGrVector(t[0]));
	front->AddVertex(CGrVector(v[3]));
	front->AddTexCoord(CGrVector(t[2]));
	front->AddVertex(CGrVector(v[2]));
	front->AddTexCoord(CGrVector(t[3]));
	front->AddVertex(CGrVector(v[6]));
	front->AddTexCoord(CGrVector(t[1]));
	front->AddVertex(CGrVector(v[7]));

	tex1->SetChild(front);
	CSgPtr<CSgSeparator> sep6 = new CSgSeparator();
	sep6->SetChild(tex1);
	flag->AddChild(sep6);

	CSgPtr<CSgPolygon> top = new CSgPolygon();

	top->AddNormal(CGrVector(n[4]));
	top->AddTexCoord(CGrVector(t[0]));
	top->AddVertex(CGrVector(v[5]));
	top->AddTexCoord(CGrVector(t[2]));
	top->AddVertex(CGrVector(v[4]));
	top->AddTexCoord(CGrVector(t[3]));
	top->AddVertex(CGrVector(v[7]));
	top->AddTexCoord(CGrVector(t[1]));
	top->AddVertex(CGrVector(v[6]));

	flag->AddChild(top);

	CSgPtr<CSgSeparator> sep7 = new CSgSeparator();
	CSgPtr<CSgTranslate> trs7 = new CSgTranslate(0., 10, 2.);
	trs7->SetChild(flag);
	sep7->SetChild(trs7);
	m_antenna->AddChild(sep7);

	return m_antenna;
	//m_ObservationTower->AddChild(sep4);
}


CSgPtr<CSgComposite> ObservationTowerFactory::ConicalFrustum(double m_height, double bottom_radius, double top_radius)
{
	CSgPtr<CSgComposite> conicalfrustum = new CSgComposite();
	CSgPtr<CSgMesh> m_sides = new CSgMesh();
	CSgPtr<CSgComposite> top = new CSgComposite();
	CSgPtr<CSgComposite> bottom = new CSgComposite();

	unsigned m_side_num = 5;
	double height_step = m_height/m_side_num;
	double radius_step = (top_radius - bottom_radius)/10;
	unsigned count1 = 0;
	// To change the radius
	double bottom_r = bottom_radius;
	for(double k = 0.0; k<m_height; k+= height_step )
	{	
		double center[] = {0.0, k, 0.0};
		double top_center[] = {0.0, k+height_step , 0.0};
		
		double top_r = bottom_r + radius_step;
		for(unsigned j = 0; j<m_side_num;j++)
		{
			double angle = (2*GR_PI)/m_side_num;
			
			double top_vertex[] = {top_center[0] + top_r * sin(angle * j), top_center[1], top_center[2] + top_r * cos(angle * j), 0};
			double bottom_vertex[] = {center[0] + bottom_r * sin(angle * j), center[1], center[2] + bottom_r* cos(angle * j), 0};
	
			m_sides->AddVertex( top_vertex );
			m_sides->AddVertex( bottom_vertex );


			if(k == 0.0)
				m_sides->AddNormal(CGrVector(sin(angle *j), 0, cos(angle*j)));

			if( j == 0)
				continue;
			
			unsigned temp= count1*(m_side_num*2);
			unsigned tl = j*2-2;
			unsigned ll = j*2-1;
			unsigned lr = j*2+1;
			unsigned tr = j*2;
			//First triangle of square
			m_sides->AddTriangleVertex(temp+tl, j, -1);
			m_sides->AddTriangleVertex(temp+ll, j, -1);
			m_sides->AddTriangleVertex(temp+lr, j, -1);

			//Second triangle of square
			m_sides->AddTriangleVertex(temp+tl, j, -1);
			m_sides->AddTriangleVertex(temp+lr, j, -1);
			m_sides->AddTriangleVertex(temp+tr, j ,-1);	
		}	
		unsigned temp2 = (count1*m_side_num*2);
		m_sides->AddTriangleVertex(temp2+(m_side_num*2) - 2, 0, -1);
		m_sides->AddTriangleVertex(temp2+(m_side_num*2) -1, 0, -1);
		m_sides->AddTriangleVertex(temp2+1, 0, -1);
		m_sides->AddTriangleVertex(temp2+(m_side_num*2) -2, 0, -1);
		m_sides->AddTriangleVertex(temp2+1, 0, -1);
		m_sides->AddTriangleVertex(temp2+0, 0 ,-1);
		count1++;
		bottom_r = top_r;
	}
	conicalfrustum->AddChild(m_sides);

	top = Disk(top_radius);
	CSgPtr<CSgTranslate> trs2 = new CSgTranslate(0, m_height, 0);
	CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
	trs2->SetChild(top);
	sep2->SetChild(trs2);

	conicalfrustum->AddChild(sep2);

	bottom = Disk(bottom_radius);
	CSgPtr<CSgRotate> rot3 = new CSgRotate(180, CGrVector(1,0,0));
	CSgPtr<CSgSeparator> sep3 = new CSgSeparator();
	rot3->SetChild(bottom);
	sep3->SetChild(rot3);

	conicalfrustum->AddChild(sep3);

	return conicalfrustum;
}

CSgPtr<CSgComposite> ObservationTowerFactory::Disk(double m_radius)
{

	CSgPtr<CSgComposite> m_disk = new CSgComposite();

	CSgPtr<CSgMesh> disk = new CSgMesh();

	unsigned m_side_num = 10;
	for(unsigned j = 0; j<m_side_num;j++)
	{
		// Sets the First Vector
		if( j == 0)
		{
			disk->AddVertex(CGrVector(0,.0,0));
			disk->AddNormal(CGrVector(0,1,0));
		}
		double angle = (2*GR_PI)/m_side_num;
		double vertex[] = { m_radius * sin(angle * j), 0.,0+ m_radius * cos(angle * j), 0};

		disk->AddVertex( vertex );

		if( j == 0)
			continue;
		
		unsigned tl = j;
		unsigned tr = j+1;

		disk->AddTriangleVertex(tl, 0, -1);
		disk->AddTriangleVertex(tr, 0, -1);
		disk->AddTriangleVertex(0, 0, -1);
	}	
	// Adds the Last Triangle
	disk->AddTriangleVertex(m_side_num, 0, -1);
	disk->AddTriangleVertex(1, 0, -1);
	disk->AddTriangleVertex(0, 0, -1);

	CSgPtr<CSgTranslate> trs2 = new CSgTranslate(0, 0., 0);
	CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
	trs2->SetChild(disk);
	sep2->SetChild(trs2);

	m_disk->AddChild(sep2);
	return m_disk;
}
CSgPtr<CSgComposite> ObservationTowerFactory::CreateBench(void)
{
	CSgPtr<CSgComposite> m_bench = new CSgComposite();

	CSgPtr<CSgComposite> m_bench_back = new CSgComposite();
	m_bench_back = Shell(1.,2.5);
	CSgPtr<CSgSeparator> sep1 = new CSgSeparator();
	CSgPtr<CSgTranslate> trs1 = new CSgTranslate(CGrVector(0.,.3, 0.));
	trs1->SetChild(m_bench_back);
	sep1->SetChild(trs1);
	m_bench->AddChild(sep1);

	CSgPtr<CSgComposite> m_bench_back_top = new CSgComposite();
	m_bench_back_top = Shell(1., 2.1);
	CSgPtr<CSgTranslate> trs2 = new CSgTranslate(CGrVector(0., 1.3, 0.));
	CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
	trs2->SetChild(m_bench_back_top);
	sep2->SetChild(trs2);
	m_bench->AddChild(sep2);

	CSgPtr<CSgComposite>  m_benchtop = new CSgComposite();
	m_benchtop = CreateDoughnut(2.1, 2.5);
	CSgPtr<CSgTranslate> trs3 = new CSgTranslate(CGrVector(0., 1.3, 0.));
	CSgPtr<CSgSeparator> sep3 = new CSgSeparator();
	trs3->SetChild(m_benchtop);
	sep3->SetChild(trs3);
	m_bench->AddChild(sep3);

	CSgPtr<CSgComposite> m_back_top = new CSgComposite();
	m_back_top = CreateDoughnut(2.0, 2.1);
	CSgPtr<CSgTranslate> trs4 = new CSgTranslate(CGrVector(0., 2.3, 0.));
	CSgPtr<CSgSeparator> sep4 = new CSgSeparator();
	trs4->SetChild(m_back_top);
	sep4->SetChild(trs4);
	m_bench->AddChild(sep4);
	
	return m_bench;
}

CSgPtr<CSgComposite> ObservationTowerFactory::CreateSign(void)
{
	CSgPtr<CSgComposite> sign = new CSgComposite();
	double v[8][4] = {{0., 0., 0., 1.},{2, 0., 0., 1.}, {2, 0., 0.1, 1.},
						{0., 0., 0.1, 1.}, {0., 2., 0., 1.}, {2, 2., 0., 1.},
						{2, 2., 0.1, 1.}, {0., 2., 0.1, 1.}};
    double n[6][4] = {{0, 0, 1, 0}, {1, 0, 0, 0}, {0, 0, -1, 0}, 
						{-1, 0, 0, 0}, {0, 1, 0, 0}, {0, -1, 0, 0}};

	double t[4][2] = {{0, 0}, {0,1}, {1, 0}, {1,1}};

	CSgPtr<CSgTexture> tex1 = new CSgTexture(m_texture2);

	CSgPtr<CSgPolygon> bottom = new CSgPolygon();
	bottom->AddNormal(CGrVector(n[5]));
	bottom->AddTexCoord(CGrVector(t[1]));
	bottom->AddVertex(CGrVector(v[0]));
	bottom->AddTexCoord(CGrVector(t[0]));
	bottom->AddVertex(CGrVector(v[1]));
	bottom->AddTexCoord(CGrVector(t[2]));
	bottom->AddVertex(CGrVector(v[2]));
	bottom->AddTexCoord(CGrVector(t[3]));
	bottom->AddVertex(CGrVector(v[3]));

	sign->AddChild(bottom);

	CSgPtr<CSgPolygon> left = new CSgPolygon();
	left->AddNormal(CGrVector(n[3]));
	left->AddTexCoord(CGrVector(t[1]));
	left->AddVertex(CGrVector(v[4]));
	left->AddTexCoord(CGrVector(t[0]));
	left->AddVertex(CGrVector(v[0]));
	left->AddTexCoord(CGrVector(t[2]));
	left->AddVertex(CGrVector(v[3]));
	left->AddTexCoord(CGrVector(t[3]));
	left->AddVertex(CGrVector(v[7]));

	sign->AddChild(left);
	

	CSgPtr<CSgPolygon> right = new CSgPolygon();

	right->AddNormal(CGrVector(n[1]));
	right->AddTexCoord(CGrVector(t[2]));
	right->AddVertex(CGrVector(v[1]));
	right->AddTexCoord(CGrVector(t[3]));
	right->AddVertex(CGrVector(v[5]));
	right->AddTexCoord(CGrVector(t[1]));
	right->AddVertex(CGrVector(v[6]));
	right->AddTexCoord(CGrVector(t[0]));
	right->AddVertex(CGrVector(v[2]));

	sign->AddChild(right);

	CSgPtr<CSgPolygon> back = new CSgPolygon();

	back->AddNormal(CGrVector(n[2]));
	back->AddTexCoord(CGrVector(t[0]));
	back->AddVertex(CGrVector(v[0]));
	back->AddTexCoord(CGrVector(t[2]));
	back->AddVertex(CGrVector(v[4]));
	back->AddTexCoord(CGrVector(t[3]));
	back->AddVertex(CGrVector(v[5]));
	back->AddTexCoord(CGrVector(t[1]));
	back->AddVertex(CGrVector(v[1]));

	sign->AddChild(back);

	CSgPtr<CSgPolygon> front = new CSgPolygon();

	front->AddNormal(CGrVector(n[0]));
	front->AddTexCoord(CGrVector(t[0]));
	front->AddVertex(CGrVector(v[3]));
	front->AddTexCoord(CGrVector(t[2]));
	front->AddVertex(CGrVector(v[2]));
	front->AddTexCoord(CGrVector(t[3]));
	front->AddVertex(CGrVector(v[6]));
	front->AddTexCoord(CGrVector(t[1]));
	front->AddVertex(CGrVector(v[7]));

	tex1->SetChild(front);
	CSgPtr<CSgSeparator> sep3 = new CSgSeparator();
	sep3->SetChild(tex1);
	sign->AddChild(sep3);

	CSgPtr<CSgPolygon> top = new CSgPolygon();

	top->AddNormal(CGrVector(n[4]));
	top->AddTexCoord(CGrVector(t[0]));
	top->AddVertex(CGrVector(v[5]));
	top->AddTexCoord(CGrVector(t[2]));
	top->AddVertex(CGrVector(v[4]));
	top->AddTexCoord(CGrVector(t[3]));
	top->AddVertex(CGrVector(v[7]));
	top->AddTexCoord(CGrVector(t[1]));
	top->AddVertex(CGrVector(v[6]));

	sign->AddChild(top);

	for(int i = 0; i < 2; i++)
	{

		if(i%2)
		{
			CSgPtr<CSgOctagonalCylinder> pole = new CSgOctagonalCylinder(4.f, 0.05f);
			CSgPtr<CSgTranslate> trs1 = new CSgTranslate(2,0, -0.05);
			CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
			trs1->SetChild(pole);
			sep2->SetChild(trs1);
			sign->AddChild(sep2);
		}
		else
		{
			CSgPtr<CSgOctagonalCylinder> pole = new CSgOctagonalCylinder(4.f, 0.05f);
			CSgPtr<CSgTranslate> trs1 = new CSgTranslate(i*2,0., -0.05);
			CSgPtr<CSgSeparator> sep2 = new CSgSeparator();
			trs1->SetChild(pole);
			sep2->SetChild(trs1);
			sign->AddChild(sep2);
		}

	}

	CSgPtr<CSgComposite> final = new CSgComposite();
	CSgPtr<CSgTranslate> trs = new CSgTranslate(5., 0., 6.);
	trs->SetChild(sign);

	CSgPtr<CSgSeparator> sep = new CSgSeparator();
	sep->SetChild(trs);
	final->AddChild(sep);

	return final;

	return CSgPtr<CSgComposite>();
}
